﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

using System.Collections.Generic;
using Tesla.Content;
using Tesla.Math;

namespace Tesla.Graphics {
    /// <summary>
    /// Light collection interface.
    /// </summary>
    public interface ILightCollection : IEnumerable<Light>, ISavable {

        /// <summary>
        /// Gets the light at the specified index.
        /// </summary>
        /// <param name="index">Zero-based index</param>
        /// <returns>Light if it exists</returns>
        Light this[int index] {
            get;
        }

        /// <summary>
        /// Gets or sets if the light collection is enabled. If disabled, will be ignored
        /// by a material's LightLogic.
        /// </summary>
        bool IsEnabled { 
            get; 
            set; 
        }

        /// <summary>
        /// Gets the number of lights in the collection.
        /// </summary>
        int LightCount { 
            get; 
        }

        /// <summary>
        /// Gets the maximum number of lights to use, meaning lights from 0 to MaxLights-1 are used
        /// when setting lights to the shader.
        /// </summary>
        int MaxLights { 
            get; 
            set; 
        }

        /// <summary>
        /// Gets or sets if lights should be sent to the shader.
        /// </summary>
        bool RefreshShader { 
            get; 
            set; 
        }

        /// <summary>
        /// Gets or sets the global ambient color.
        /// </summary>
        Color GlobalAmbient { 
            get; 
            set; 
        }

        /// <summary>
        /// Adds a new light to the collection.
        /// </summary>
        /// <param name="light">Light to add</param>
        /// <returns>The index of which the light was added at, or -1 if the light was null and not added.</returns>
        int Add(Light light);

        /// <summary>
        /// Removes the light from the collection.
        /// </summary>
        /// <param name="light">Light to remove</param>
        /// <returns>True if the light was removed</returns>
        bool Remove(Light light);

        /// <summary>
        /// Removes the light at the specified index.
        /// </summary>
        /// <param name="index">Zero-based index</param>
        /// <returns>True if a light at the index was removed</returns>
        bool RemoveAt(int index);

        /// <summary>
        /// Clears all the lights from the collection.
        /// </summary>
        void Clear();

        /// <summary>
        /// Resets the collection's data and copies the input light collection's data.
        /// </summary>
        /// <param name="lights">Light collection to copy from</param>
        void Set(ILightCollection lights);

        /// <summary>
        /// Copies all the lights contained from the specified collection,
        /// but preserves the lights already present in this collection.
        /// </summary>
        /// <param name="copyFrom">Light collection to copy from</param>
        void CopyLights(ILightCollection copyFrom);

        /// <summary>
        /// Copies the specified amount of lights contained from the specified collection,
        /// but preserves the lights already present in this collection.
        /// </summary>
        /// <param name="copyFrom">Light collection to copy from</param>
        /// <param name="copyCount">Number of lights to copy</param>
        void CopyLights(ILightCollection copyFrom, int copyCount);

        /// <summary>
        /// Sorts the lights. Lights that affect the renderable the most
        /// are lower-indexed.
        /// </summary>
        /// <param name="renderable">Renderable to use for sorting the lights</param>
        void SortLights(IRenderable renderable);
    }
}
